package models

import (
	"errors"
	"fmt"
	"time"

	"github.com/beego/beego/v2/client/orm"
)

// Coupon 优惠券模型
type Coupon struct {
	BaseModel
	Name           string  `orm:"size(100)" json:"name"`
	Code           string  `orm:"size(50);unique" json:"code"`               // 优惠券代码
	Type           int8    `orm:"default(1)" json:"type"`                    // 0:折扣券, 1:现金券, 2:满减券, 3:时长券, 4:免费券, 5:赠品券, 6:特价券
	Value          float64 `orm:"digits(10);decimals(2)" json:"value"`       // 优惠券面值
	Discount       float64 `orm:"digits(10);decimals(2)" json:"discount"`    // 折扣券折扣率
	Duration       int     `orm:"default(0)" json:"duration"`                // 时长券时长（分钟）
	MinConsume     float64 `orm:"digits(10);decimals(2)" json:"min_consume"` // 最低消费金额
	ValidDays      int     `orm:"default(30)" json:"valid_days"`             // 有效期天数
	StartTime      int64   `orm:"" json:"start_time"`                        // 开始时间
	EndTime        int64   `orm:"" json:"end_time"`                          // 结束时间
	TotalCount     int     `orm:"default(0)" json:"total_count"`             // 发行总量，0表示不限量
	UsedCount      int     `orm:"default(0)" json:"used_count"`              // 已使用数量
	IssuedCount    int     `orm:"default(0)" json:"issued_count"`            // 已发放数量
	PerLimit       int     `orm:"default(1)" json:"per_limit"`               // 每人限领数量
	Description    string  `orm:"size(500)" json:"description"`
	UseRules       string  `orm:"size(500)" json:"use_rules"`        // 使用规则
	Status         int8    `orm:"default(1)" json:"status"`          // 1:正常, 0:禁用
	ApplicableType    int8   `orm:"default(0)" json:"applicable_type"` // 0:全场通用, 1:指定门店, 2:指定包厢
	ApplicableIds     string `orm:"size(1000)" json:"applicable_ids"`  // 适用的门店或包厢ID，JSON格式存储
	AvailableWeekdays string `orm:"size(255)" json:"available_weekdays"` // 可用星期, JSON array
	AvailableTimes    string `orm:"size(1000)" json:"available_times"`   // 可用时段, JSON array of time ranges
}

// TableName 设置表名
func (c *Coupon) TableName() string {
	return "ss_coupon"
}

// GetCouponById 根据ID获取优惠券信息
func GetCouponById(id int64) (*Coupon, error) {
	coupon := &Coupon{BaseModel: BaseModel{Id: id}}
	o := orm.NewOrm()
	err := o.Read(coupon)
	return coupon, err
}

// GetCouponByCode 根据代码获取优惠券信息
func GetCouponByCode(code string) (*Coupon, error) {
	coupon := &Coupon{Code: code}
	o := orm.NewOrm()
	err := o.Read(coupon, "Code")
	return coupon, err
}

// GetCouponList 获取优惠券列表
func GetCouponList(page, pageSize int, filters map[string]interface{}) ([]*Coupon, int64, error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(Coupon))

	// 应用过滤条件
	if name, ok := filters["name"].(string); ok && name != "" {
		qs = qs.Filter("name__contains", name)
	}

	if code, ok := filters["code"].(string); ok && code != "" {
		qs = qs.Filter("code__contains", code)
	}

	if couponType, ok := filters["type"].(int8); ok {
		qs = qs.Filter("type", couponType)
	}

	if status, ok := filters["status"].(int8); ok {
		qs = qs.Filter("status", status)
	}

	if applicableType, ok := filters["applicable_type"].(int8); ok {
		qs = qs.Filter("applicable_type", applicableType)
	}

	// 排除已删除的记录
	qs = qs.Filter("is_deleted", 0)

	// 获取总数
	total, _ := qs.Count()

	// 分页查询
	var coupons []*Coupon
	_, err := qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&coupons)

	return coupons, total, err
}

// CreateCoupon 创建优惠券
func CreateCoupon(coupon *Coupon) (int64, error) {
	o := orm.NewOrm()
	id, err := o.Insert(coupon)
	return id, err
}

// UpdateCoupon 更新优惠券
func UpdateCoupon(coupon *Coupon) error {
	o := orm.NewOrm()
	_, err := o.Update(coupon)
	return err
}

// DeleteCoupon 删除优惠券（软删除）
func DeleteCoupon(id int64) error {
	o := orm.NewOrm()
	coupon := &Coupon{BaseModel: BaseModel{Id: id}}
	if err := o.Read(coupon); err != nil {
		return err
	}

	coupon.IsDeleted = 1
	_, err := o.Update(coupon, "IsDeleted")
	return err
}

// IncreaseCouponUsedCount 增加优惠券已使用数量
func IncreaseCouponUsedCount(id int64) error {
	o := orm.NewOrm()
	_, err := o.QueryTable(new(Coupon)).Filter("id", id).Update(orm.Params{
		"used_count": orm.ColValue(orm.ColAdd, 1),
		"updated_at": time.Now().Unix(),
	})
	return err
}

// GetValidCoupons 获取有效的优惠券列表
func GetValidCoupons() ([]*Coupon, error) {
	o := orm.NewOrm()
	var coupons []*Coupon
	now := time.Now().Unix()
	_, err := o.QueryTable(new(Coupon)).
		Filter("status", 1).
		Filter("is_deleted", 0).
		Filter("start_time__lte", now).
		Filter("end_time__gte", now).
		All(&coupons)
	return coupons, err
}

// IncreaseCouponIssuedCount 增加优惠券已发放数量
func IncreaseCouponIssuedCount(id int64) error {
	o := orm.NewOrm()
	_, err := o.QueryTable(new(Coupon)).Filter("id", id).Update(orm.Params{
		"issued_count": orm.ColValue(orm.ColAdd, 1),
		"updated_at":   time.Now().Unix(),
	})
	return err
}

// CheckCouponAvailable 检查优惠券是否可领取
func CheckCouponAvailable(couponId int64, memberId int64) (bool, string) {
	o := orm.NewOrm()

	// 获取优惠券信息
	coupon := &Coupon{BaseModel: BaseModel{Id: couponId}}
	err := o.Read(coupon)
	if err != nil {
		return false, "优惠券不存在"
	}

	// 检查优惠券状态
	if coupon.Status != 1 {
		return false, "优惠券已禁用"
	}

	// 检查发放数量限制
	if coupon.TotalCount > 0 && coupon.IssuedCount >= coupon.TotalCount {
		return false, "优惠券已领完"
	}

	// 检查每人限领数量
	if coupon.PerLimit > 0 {
		count, err := o.QueryTable(new(CouponIssue)).
			Filter("coupon_id", couponId).
			Filter("member_id", memberId).
			Count()
		if err == nil && int(count) >= coupon.PerLimit {
			return false, fmt.Sprintf("每人最多可领取%d张", coupon.PerLimit)
		}
	}

	return true, ""
}

// UseCouponTx 在事务中使用优惠券
func UseCouponTx(tx orm.TxOrmer, couponId int64, userId int64, orderId int64) error {
	// 获取优惠券信息
	coupon := &CouponIssue{BaseModel: BaseModel{Id: couponId}}
	err := tx.Read(coupon)
	if err != nil {
		return err
	}

	// 检查优惠券是否属于当前用户
	if coupon.MemberId != userId {
		return errors.New("优惠券不属于当前用户")
	}

	// 检查优惠券状态
	if coupon.Status != 0 {
		return errors.New("优惠券状态异常")
	}

	// 检查优惠券是否过期
	if coupon.ExpireTime > 0 && coupon.ExpireTime < time.Now().Unix() {
		return errors.New("优惠券已过期")
	}

	// 更新优惠券状态为已使用
	coupon.Status = 1
	coupon.UsedTime = time.Now().Unix()
	coupon.OrderId = orderId
	coupon.UpdatedAt = time.Now().Unix()

	_, err = tx.Update(coupon)
	return err
}

// GetCouponIssueCount 获取优惠券发放总数
func GetCouponIssueCount(franchiseId int64) (int64, error) {
	o := orm.NewOrm()
	var count int64

	// 构建查询条件
	whereClause := "is_deleted = 0"
	params := []interface{}{}

	// 如果是加盟商，添加加盟商过滤条件
	if franchiseId > 0 {
		whereClause += " AND franchise_id = ?"
		params = append(params, franchiseId)
	}

	// 执行查询
	err := o.Raw("SELECT COUNT(*) FROM ss_coupon_issue WHERE "+whereClause, params...).QueryRow(&count)
	return count, err
}
